package gui;

import gui.eventListener.Mouse;
import gui.netbeans.ButtonPanel;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import dados.Curva;
import desenhando.EstadoDesenhando;

public class DrawPanel extends JPanel {
	public static final long SPEED_INCREMENT = 50;
	public static final long MAX_SPACING_BETWEEN_FRAMES = 500;
	public static final long MIN_SPACING_BETWEEN_FRAMES = 50;

	private JFrame frame;
	private EstadoDesenhando draw;
	private JButton button; // TODO Can this atribute be deleted?
	private Mouse mouse;

	private ButtonPanel menu;

	// General animation variables
	private long speed;

	// General visibility variables
	private boolean allCurvesVisible;
	private boolean allPolygonalsVisible;
	private boolean allControlPointsVisible;
	private boolean allSecondaryPolygonalsVisible;

	public DrawPanel(JFrame frame, EstadoDesenhando draw, ButtonPanel menu) {
		super();
		this.setPreferredSize(new Dimension(813, 600));
		this.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		this.setBackground(Color.WHITE);
		this.frame = frame;
		this.draw = draw;
		this.button = new JButton();

		// inicializando menu
		this.menu = menu;
		this.menu.inicializando(this);

		this.speed = DrawPanel.MAX_SPACING_BETWEEN_FRAMES;

		this.allCurvesVisible = true;
		this.allPolygonalsVisible = true;
		this.allControlPointsVisible = true;
		this.allSecondaryPolygonalsVisible = false;

		this.allCurvesVisible = true;

		// Adding a mouse listener to the frame
		mouse = new Mouse(this);
		frame.addMouseListener(mouse);
		frame.addMouseMotionListener(mouse);

	}

	public void update() {
		frame.repaint();
		frame.validate();
	}

	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		draw.drawAllControlPoints(g);
		draw.drawAllMainControlPolygonals(g);
		draw.drawAllCurves(g);
		this.draw.drawSecondaryPolygonals(g);

	}

	public double animationStep() {
		double t = 0;
		if (this.draw.isAnimatedPolygonals()) {

			for (int i = 0; i < this.draw.getCurves().size(); i++) {
				Curva c = this.draw.getCurves().get(i);
				t = c.animationStep(this.getGraphics());

			}

			this.update();
			try {
				Thread.sleep(this.speed);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return t;
	}

	public void fasterAnimation() {
		this.speed += SPEED_INCREMENT;
		if (this.speed > DrawPanel.MAX_SPACING_BETWEEN_FRAMES) {
			this.speed = DrawPanel.MAX_SPACING_BETWEEN_FRAMES;
		}
	}

	public void slowerAnimation() {
		this.speed -= SPEED_INCREMENT;
		if (this.speed < DrawPanel.MIN_SPACING_BETWEEN_FRAMES) {
			this.speed = DrawPanel.MIN_SPACING_BETWEEN_FRAMES;
		}
	}

	// GETTERS AND SETTERS
	public EstadoDesenhando getDraw() {
		return draw;
	}

	public void setDraw(EstadoDesenhando draw) {
		this.draw = draw;
	}

	public boolean isAllCurvesVisible() {
		return allCurvesVisible;
	}

	public void setAllCurvesVisible(boolean allCurvesVisible) {
		this.allCurvesVisible = allCurvesVisible;
	}

	public boolean isAllPolygonalsVisible() {
		return allPolygonalsVisible;
	}

	public void setAllPolygonalsVisible(boolean allPolygonalsVisible) {
		this.allPolygonalsVisible = allPolygonalsVisible;
	}

	public Mouse getMouse() {
		return mouse;
	}

	public void setMouse(Mouse mouse) {
		this.mouse = mouse;
	}

	public ButtonPanel getMenu() {
		return menu;
	}

	public void setMenu(ButtonPanel menu) {
		this.menu = menu;
	}

	public boolean isAllControlPointsVisible() {
		return allControlPointsVisible;
	}

	public void setAllControlPointsVisible(boolean allControlPointsVisible) {
		this.allControlPointsVisible = allControlPointsVisible;
	}

	public long getSpeed() {
		return speed;
	}

	public void setSpeed(long speed) {

		this.speed = speed;
	}

	public boolean isAllSecondaryPolygonalsVisible() {
		return allSecondaryPolygonalsVisible;
	}

	public void setAllSecondaryPolygonalsVisible(boolean allSecondaryPolygonalsVisible) {
		this.allSecondaryPolygonalsVisible = allSecondaryPolygonalsVisible;
	}

}
